<template>
  <!-- 弹出层 -->
  <t-popup v-model:visible="visiblePopup" placement="bottom-left" trigger="click" :disabled="!visiblePopup">
    <!-- 多行文本框 -->
    <t-textarea
      v-bind="$attrs"
      v-model:value="textareaValue"
      :tips="tips"
      @change="handleChange"
      @keypress="handleKeypress"
    />
    <!-- 用户列表 -->
    <template #content>
      <ul class="t-select__list">
        <li v-for="_ in computedOptions" :key="_.id" class="t-select-option t-size-m" @click="handleSelectUser(_)">
          {{ _.nickname }}
        </li>
        <li v-show="computedOptions.length === 0">未匹配到该用户</li>
      </ul>
    </template>
  </t-popup>
</template>

<script setup lang="ts">
import { TextareaValue } from 'tdesign-vue-next';
import { computed, PropType, ref, watch } from 'vue';

// props
const props = defineProps({
  options: {
    type: Array as PropType<{ id: number; nickname: string }[]>,
    default: () => [],
  },
});
// 显示弹出层
const visiblePopup = ref(false);
// 多行文本内容
const textareaValue = defineModel('value', { type: String, default: '' });
// 过滤的值
const filterValue = computed(() => {
  const lastIndex = textareaValue.value.lastIndexOf('@');
  if (lastIndex === -1) return '';
  const text = textareaValue.value.substring(lastIndex + 1);
  const splitIndex = text.indexOf(' ');
  return splitIndex === -1 ? text : text.substring(0, splitIndex);
});
// 计算的选项
const computedOptions = computed(() => {
  return props.options.filter((item) => item.nickname.indexOf(filterValue.value) > -1);
});
// 处理改变
const handleChange = (value: TextareaValue) => {
  value = value.toString();
  const splitIndex = value.lastIndexOf(' ');
  if (!value.substring(splitIndex).includes('@')) visiblePopup.value = false;
};
// 处理按键
const handleKeypress = (value: TextareaValue, context: { e: KeyboardEvent }) => {
  const { key } = context.e;
  if (key === '@') visiblePopup.value = true;
};
// 处理选择用户
const handleSelectUser = (userInfo: Record<string, any>) => {
  visiblePopup.value = false;
  const lastIndex = textareaValue.value.lastIndexOf('@');
  textareaValue.value = `${textareaValue.value.substring(0, lastIndex)}@${userInfo.nickname} `;
};
// 选择的keys
const selectedKeys = defineModel('selectedKeys', { type: Array as PropType<Number[]>, default: [] });
watch(
  () => textareaValue.value,
  (newValue) => {
    const result: number[] = [];
    props.options.forEach((item) => {
      const key = `@${item.nickname} `;
      if (newValue.includes(key)) result.push(item.id);
    });
    selectedKeys.value = result;
  },
);
// 提示
const tips = computed(() => {
  let result = '';
  selectedKeys.value.forEach((id, index) => {
    const nickname = props.options.find((item) => item.id === id)?.nickname;
    if (nickname) {
      if (index === 0) result += '提及用户：';
      if (index > 0) result += '、';
      result += nickname;
    }
  });
  return result;
});
</script>

<style lang="less" scoped></style>
